﻿namespace KingerRobot.SenturyMDC.Biz
{
    public class Alarm
    {
        private static readonly object lockobject = new object();
        #region 单例模式
        public static Alarm Instance { get { return Singleton.Create<Alarm>(); } }
        /// <summary>
        /// 构造函数
        /// </summary>
        private Alarm()
        {
        }
        #endregion

        private ConcurrentDictionary<long, AlarmData> xstore = new ConcurrentDictionary<long, AlarmData>();
        class AlarmData
        {
            /// <summary>
            /// 机器ID
            /// </summary>
            public long EquipId { get; set; }
            /// <summary>
            /// 报警标识
            /// </summary>
            public int AlarmNo { get; set; }
            /// <summary>
            /// 报警信息
            /// </summary>
            public string AlarmCode { get; set; }
            /// <summary>
            /// 报警信息
            /// </summary>
            public string AlarmMsg { get; set; }
            /// <summary>
            /// 任务流水号
            /// </summary>
            public int? TaskNo { get; set; }
            /// <summary>
            /// 任务流水号
            /// </summary>
            public int? TaskNo2 { get; set; }
        }
        public int AddAlarm(long equipId, int alarmNo)
        {
            lock (lockobject)
            {
                xstore.TryGetValue(equipId, out var alarm);
                if (alarm == null)
                {
                    return updateAlarm(equipId, alarmNo);
                }
                if (alarm.AlarmNo != alarmNo)
                {
                    return updateAlarm(equipId, alarmNo);
                }
            }
            return 0;
        }

        /// <summary>
        /// 报警信号增加
        /// </summary>
        /// <param name="equipId">设备ID</param>
        /// <param name="alarmNo">报警编号：0 正常；</param>
        /// <param name="alarmCode">报警代码（多个 alarmNo 值链接）</param>
        /// <param name="alarmMsg">报警内容</param>
        /// <returns></returns>
        public int AddAlarm(long equipId, int alarmNo, string alarmCode, string alarmMsg)
        {
            if (equipId == 0)
            {
                return 0;
            }

            lock (lockobject)
            {
                xstore.TryGetValue(equipId, out var alarm);
                if (alarmNo == 0)
                {
                    if (alarm is not null && alarm.AlarmNo != alarmNo)
                    {
                        // 正常
                        return updateAlarm(equipId, alarmNo, string.Empty, string.Empty);
                    }

                    return 1;
                }

                if (alarm == null)
                {
                    // 报警第一次添加
                    return updateAlarm(equipId, alarmNo, alarmCode, alarmMsg);
                }

                if (!alarm.AlarmCode.Equals(alarmCode))
                {
                    // 持续报警
                    return updateAlarm(equipId, alarmNo, alarmCode, alarmMsg);
                }
            }
            return 0;
        }

        /// <summary>
        /// 报警信号增加
        /// </summary>
        /// <param name="equipId">设备ID</param>
        /// <param name="alarmNo">报警编号：0 正常；</param>
        /// <param name="alarmCode">报警代码（多个 alarmNo 值链接）</param>
        /// <param name="alarmMsg">报警内容</param>
        /// <returns></returns>
        public int AddAlarmV2(long equipId, int alarmNo, string alarmCode, string alarmMsg, int? taskNo)
        {
            lock (lockobject)
            {
                xstore.TryGetValue(equipId, out var alarm);
                if (alarmNo == 0)
                {
                    if (alarm is not null && alarm.AlarmNo != alarmNo)
                    {
                        // 正常
                        return updateAlarmV2(equipId, alarmNo, string.Empty, string.Empty, taskNo);
                    }

                    return 1;
                }

                if (alarm == null)
                {
                    // 报警第一次添加
                    return updateAlarmV2(equipId, alarmNo, alarmCode, alarmMsg, taskNo);
                }

                if (!alarm.AlarmCode.Equals(alarmCode))
                {
                    // 持续报警
                    return updateAlarmV2(equipId, alarmNo, alarmCode, alarmMsg, taskNo);
                }
            }
            return 0;
        }


        public int AddAlarmV3(long equipId, int alarmNo, string alarmCode, string alarmMsg, int taskNo = 0, int taskNo2 = 0)
        {
            lock (lockobject)
            {
                xstore.TryGetValue(equipId, out var alarm);
                if (alarmNo == 0)
                {
                    if (alarm?.AlarmNo != alarmNo)
                    {
                        // 正常
                        return updateAlarmV3(equipId, alarmNo, string.Empty, string.Empty, taskNo, taskNo2);
                    }

                    return 1;
                }

                if (alarm == null)
                {
                    // 报警第一次添加
                    return updateAlarmV3(equipId, alarmNo, alarmCode, alarmMsg, taskNo, taskNo2);
                }
                //临时加注 AlarmCode为空，报错
                //if (string.IsNullOrEmpty(alarm.AlarmCode))
                //{
                //    return 0 ;
                //}
                if (!alarm.AlarmCode.Equals(alarmCode))
                {
                    // 持续报警
                    return updateAlarmV3(equipId, alarmNo, alarmCode, alarmMsg, taskNo, taskNo2);
                }
            }
            return 0;
        }
        private int updateAlarmV2(long equipId, int alarmNo, string alarmCode, string alarmMsg, int? taskNo)
        {
            var alarm = new AlarmData()
            {
                EquipId = equipId,
                AlarmNo = alarmNo,
                AlarmCode = alarmCode,
                AlarmMsg = alarmMsg,
                TaskNo = taskNo
            };
            var result = updateAlarmV3(alarm);
            if (result >= 1)
            {
                xstore.AddOrUpdate(equipId, alarm, (key, oldValue) => { return alarm; });
            }
            return 1;
        }

        private int updateAlarmV3(long equipId, int alarmNo, string alarmCode, string alarmMsg, int? taskNo, int? taskNo2)
        {
            var alarm = new AlarmData()
            {
                EquipId = equipId,
                AlarmNo = alarmNo,
                AlarmCode = alarmCode,
                AlarmMsg = alarmMsg,
                TaskNo = taskNo,
                TaskNo2 = taskNo2
            };
            var result = updateAlarmV4(alarm);
            if (result >= 1)
            {
                xstore.AddOrUpdate(equipId, alarm, (key, oldValue) => { return alarm; });
            }
            return 1;
        }


        private int updateAlarmV3(AlarmData alarm)
        {
            try
            {
                var service = K8.RSF.Client.Create<IEquiqService>();
                service.UpdateAlarmV3(alarm.EquipId, alarm.AlarmNo, alarm.AlarmCode, alarm.AlarmMsg, alarm.TaskNo);
                return 1;
            }
            catch
            {
                return 0;
            }
        }


        private int updateAlarm(long equipId, int alarmNo)
        {
            var alarm = new AlarmData()
            {
                EquipId = equipId,
                AlarmNo = alarmNo,
            };
            var result = updateAlarm(alarm);
            if (result >= 1)
            {
                xstore.AddOrUpdate(equipId, alarm, (key, oldValue) => { return alarm; });
            }
            return 1;
        }

        private int updateAlarm(long equipId, int alarmNo, string alarmCode, string alarmMsg)
        {
            var alarm = new AlarmData()
            {
                EquipId = equipId,
                AlarmNo = alarmNo,
                AlarmCode = alarmCode,
                AlarmMsg = alarmMsg,
            };
            var result = updateAlarmV2(alarm);
            if (result >= 1)
            {
                xstore.AddOrUpdate(equipId, alarm, (key, oldValue) => { return alarm; });
            }
            return 1;
        }
        private int updateAlarm(AlarmData alarm)
        {
            try
            {
                var service = K8.RSF.Client.Create<IEquiqService>();
                service.UpdateAlarm(alarm.EquipId, alarm.AlarmNo);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        private int updateAlarmV2(AlarmData alarm)
        {
            try
            {
                var service = K8.RSF.Client.Create<IEquiqService>();
                service.UpdateAlarmV2(alarm.EquipId, alarm.AlarmNo, alarm.AlarmCode, alarm.AlarmMsg);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        private int updateAlarmV4(AlarmData alarm)
        {
            try
            {
                var service = K8.RSF.Client.Create<IEquiqService>();
                service.UpdateAlarmV4(alarm.EquipId, alarm.AlarmNo, alarm.AlarmCode, alarm.AlarmMsg, alarm.TaskNo, alarm.TaskNo2);
                return 1;
            }
            catch
            {
                return 0;
            }
        }

    }
}
